using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace gitPull
{
    internal class Program
    {

        private const string SetDef = "checkout .";
        private const string Checkout = "checkout develop";
        private const string pull = "pull";
        private const string clean = "clean -fdx";
        private const string configFileName = "config.txt";
        bool IsFdx = false;
        HashSet<string> directories;
        string configPath;



        [STAThread]
        private static void Main(string[] args)
        {
            Program program = new Program();
            program.Start();
        }

        private void Start()
        {
            directories = new();
            configPath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), configFileName);


            SelectFunc();
            Console.WriteLine("按任意键退出...");
            Console.ReadKey();
        }

        private void DefFunc()
        {
            ReadConfig(directories, configPath);
            // 如果配置文件不存在或没有有效路径，使用文件夹选择对话框
            if (directories.Count == 0)
            {
                AddDefPath(directories, configPath);
            }
            GitFuncc(directories);
        }

        // ... existing code ...
        private void GitFuncc(HashSet<string> directories)
        {
            // 处理所有目录
            if (directories.Count > 0)
            {
                Console.WriteLine("");
                int i = 0;
                foreach (string dir in directories)
                {
                    Console.WriteLine($"目录{i + 1}: {dir}----------");
                    i++;
                }
                Console.WriteLine("");

                // 并行处理目录
                Parallel.ForEach(directories, directory =>
                {
                    Console.WriteLine($"处理目录: {directory}----------");
                    Console.WriteLine("");

                    // 获取子目录并并行执行Git命令
                    string[] subDirectories = Directory.GetDirectories(directory);

                    Parallel.ForEach(subDirectories, subDirectory =>
                    {
                        lock (Console.Out) // 确保控制台输出不会混乱
                        {
                            Console.WriteLine($"------子目录: {subDirectory}----------");
                        }
                        ExecuteGitCommand(subDirectory, SetDef);
                        if (IsFdx)
                            ExecuteGitCommand(subDirectory, clean);
                        ExecuteGitCommand(subDirectory, Checkout);
                        ExecuteGitCommand(subDirectory, pull);
                        lock (Console.Out)
                        {
                            Console.WriteLine("-------------------------");
                            Console.WriteLine("");
                        }
                    });
                });
            }
            else
            {
                Console.WriteLine("未选择有效目录");
            }
        }
        // ... existing code ...

        private void CallPull(string subDirectory)
        {
            ExecuteGitCommand(subDirectory, SetDef);
            ExecuteGitCommand(subDirectory, clean);
            ExecuteGitCommand(subDirectory, Checkout);
            ExecuteGitCommand(subDirectory, pull);
        }

        void SelectFunc()
        {
            Console.WriteLine("--------选择执行选项:------");
            Console.WriteLine("----R键 执行读取配置文件，A键 执行添加路径，F键执行FDX,Enter 默认执行----");
            ConsoleKeyInfo input = Console.ReadKey();
            Console.WriteLine(); // 换行



            switch (input.Key)
            {
                case ConsoleKey.A:
                    // 添加路径
                    ReadConfig(directories, configPath);
                    AddDefPath(directories, configPath);
                    DefFunc();
                    break;
                case ConsoleKey.F:
                    IsFdx = true;
                    Console.WriteLine("执行FDX模式");
                    DefFunc();
                    break;
                case ConsoleKey.R:
                case ConsoleKey.Enter:
                    // 默认执行，不进行任何特殊操作
                    Console.WriteLine("执行默认操作");
                    DefFunc();
                    break;

                default:
                    Console.WriteLine("无效输入，执行默认操作");
                    DefFunc();
                    break;
            }
        }

        private void ReadConfig(HashSet<string> directories, string configPath)
        {

            // 尝试从配置文件读取路径列表
            if (File.Exists(configPath))
            {
                try
                {
                    string[] lines = File.ReadAllLines(configPath);
                    foreach (string line in lines)
                    {
                        string path = line.Trim();
                        if (Directory.Exists(path))
                        {
                            directories.Add(path);
                        }
                        else if (!string.IsNullOrEmpty(path))
                        {
                            Console.WriteLine($"配置文件中的路径无效: {path}");
                        }
                    }
                    Console.WriteLine($"从配置文件读取了 {directories.Count} 个目录");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"读取配置文件时出错: {ex.Message}");
                }
            }
        }

        private void AddDefPath(HashSet<string> directories, string configPath)
        {
            FolderBrowserDialog folderBrowser = new FolderBrowserDialog();
            folderBrowser.Description = "请选择要处理的目录";
            if (folderBrowser.ShowDialog() == DialogResult.OK)
            {
                Console.WriteLine("选择的目录: " + folderBrowser.SelectedPath);
                directories.Add(folderBrowser.SelectedPath);

                // 将选择的路径保存到配置文件
                try
                {
                    File.WriteAllLines(configPath, directories);
                    Console.WriteLine("路径已保存到配置文件");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"保存配置文件时出错: {ex.Message}");
                }
            }
        }

        public void ExecuteGitCommand(string workingDirectory, string gitCommand)
        {
            ProcessStartInfo processStartInfo = new ProcessStartInfo()
            {
                FileName = "git.exe",
                WorkingDirectory = workingDirectory,
                Arguments = gitCommand,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                CreateNoWindow = true,
                UseShellExecute = false
            };
            using (Process process = new Process() { StartInfo = processStartInfo })
            {
                Console.WriteLine(gitCommand + " 目录： " + workingDirectory);
                process.Start();
                process.WaitForExit();
                string end = process.StandardOutput.ReadToEnd();
                string err = process.StandardError.ReadToEnd();
                Console.WriteLine($"结束日志：{end}");
                Console.WriteLine($"错误信息：{err}");
                process.Close();

                // 检查是否需要添加到全局安全目录
                if (!string.IsNullOrEmpty(err) &&
                    (err.Contains("safe.directory") || err.Contains("To add an exception for this directory, call") || err.Contains("add this repository to the global safe directory")))
                {
                    Console.WriteLine("检测到需要添加到全局安全目录，正在自动添加...");
                    AddToGlobalSafeDirectory(workingDirectory);
                    CallPull(workingDirectory);

                }
            }
        }

        private void AddToGlobalSafeDirectory(string repoPath)
        {
            repoPath = repoPath.Replace('\\', '/');
            ProcessStartInfo psi = new ProcessStartInfo()
            {
                FileName = "git.exe",
                Arguments = $"config --global --add safe.directory \"{repoPath}\"",
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                CreateNoWindow = true,
                UseShellExecute = false
            };
            using (Process process = new Process() { StartInfo = psi })
            {
                process.Start();
                process.WaitForExit();
                string output = process.StandardOutput.ReadToEnd();
                string error = process.StandardError.ReadToEnd();
                process.Close();
                Console.WriteLine($"安全目录添加结果：{output}");
                if (!string.IsNullOrEmpty(error))
                    Console.WriteLine($"安全目录添加错误：{error}");
            }
        }
    }
}